/*
 * Condition.h
 *
 *  Created on: 01.10.2012
 *      Author: Lapchinskiy
 */
#include "Global_types.h"
#include "BuildConfig.h"
#include "Logging.h"
#include "Block.h"
#include "ArrayList.h"
#include "ConditionVariable.h"
#include "stdarg.h"
#ifndef CONDITION_H_
#define CONDITION_H_
//#include "Global_includes.h"
template<class T>
class Condition
  {
public:
  ~Condition();
  //Condition(int operandNum, ...);
  Block* step(void);
  Condition(T* firstOperand, T (ConditionVariable<T>::*)(T*), T* secondOperand,
      bool (ConditionVariable<T>::*)(T*), T* checkVal);
  bool check();
private:
  T (ConditionVariable<T>::*opFunc)(T*);
  ConditionVariable<T> *checkValue;
  ArrayList *conVarList;
  ArrayList *operatorList;
  bool (ConditionVariable<T>::*logicOperator)(T*);
  };

//template<class T>
//Condition<T>::Condition(int operandNum, ...) {
//	conVarList = new ArrayList<ConditionVariable<T> >();
//	operatorList = new ArrayList<T*(ConditionVariable<T>::*)(T*)>();
//	va_list vl;
//	va_start(vl, (operandNum*2+1));
//
//	for (uint8_t i = 0; i < operandNum - 1; i++) {
//		conVarList->add(new ConditionVariable<T>(va_arg(vl,T*)));
//		opFunc = va_arg(vl,T*(ConditionVariable<T>::*)(T*));
//		operatorList->add(&opFunc);
//	}
//	conVarList->add(new ConditionVariable<T>(va_arg(vl,T*)));
//	logicOperator = va_arg(vl,bool (ConditionVariable<T>::*)(T*));
//	checkValue = new ConditionVariable<T>(va_arg(vl,T*));
//	va_end(vl);
//
//}

template<class T>
Condition<T>::Condition(T* firstOperand, T (ConditionVariable<T>::*pOpFunc)(T*),
    T* secondOperand, bool (ConditionVariable<T>::*logicOp)(T*), T* checkVal) 
  {
    conVarList = new ArrayList();
    operatorList = new ArrayList();
    conVarList->add((void*) (new ConditionVariable<T>(firstOperand)));
    opFunc = pOpFunc;
    operatorList->add(((void*) &opFunc));
    conVarList->add((void*) (new ConditionVariable<T>(secondOperand)));
    logicOperator = logicOp;
    checkValue = new ConditionVariable<T>(checkVal);
  }
template<class T>
bool Condition<T>::check()
  {
    bool checkResult;
    T tempVar;
    ConditionVariable<T> *temp = new ConditionVariable<T>(&tempVar);
    tempVar = *(((ConditionVariable<T>*) (conVarList->get(0)))->getValue());
    for (uint8_t i = 1; i < conVarList->getLength(); i++)
      {
        tempVar = (temp
            ->**(T (ConditionVariable<T>::**)(T*)) (operatorList->get(i - 1)))(
            ((ConditionVariable<T>*) (conVarList->get(i)))->getValue());
      }
    checkResult = (temp->*logicOperator)(checkValue->getValue());
    delete temp;
    return checkResult;
  }

template<class T>
Condition<T>::~Condition()
  {
    delete conVarList;
    delete operatorList;
    delete checkValue;
  }

#endif /* CONDITION_H_ */
